/*	C#.NET exec to run as VisualSVN Post-commit hook to talk directly to Pivotal Tracker
	Author: Jim Palmer - overset.com
	Compile:
		csc.exe /out:svn-post-commit.exe svn-post-commit.cs
	Setup:
		1. drop svn-post-commit.exe in %VISUALSVN_SERVER%\bin\ directory with proper permissions
		2. acquire your Pivotal Tracker API Token from the Profile section to be used in Post-commit arguments below
		3. add to VisualSVN Post-commit hook on specific repositories:
			"%VISUALSVN_SERVER%\bin\svn-post-commit.exe" "<TOKEN>" "%2" %2
		4. make sure to replace the <TOKEN> with your Pivotal API Token hash
*/
namespace mmsa {
	
	using System;
	using System.Diagnostics;
	using System.IO;
	using System.Net;
	using System.Text;
	using System.Text.RegularExpressions;
	
	public class SvnPostCommit {
		
		private static string svnPath = Environment.GetEnvironmentVariable("VISUALSVN_SERVER");
		
		private static int Main(string[] args) {
			
			if (args.Length < 3) {
				Console.Error.WriteLine("Invalid arguments sent - <TOKEN> <REPOSITORY> <REV> required");
				return 1;
			}
			
			if (string.IsNullOrEmpty(svnPath)) {
				Console.Error.WriteLine("VISUALSVN_SERVER environment variable does not exist. VisualSVN installed?");
				return 1;
			}
			
			// fetch author
			Process procAuthor = new Process();
			procAuthor.StartInfo = new System.Diagnostics.ProcessStartInfo(svnPath + @"bin\svnlook.exe", @"author """ + args[1] + @""" -r " + args[2]);
			procAuthor.StartInfo.RedirectStandardOutput = true;
			procAuthor.StartInfo.UseShellExecute = false;
	        procAuthor.Start();
			StringBuilder output = new StringBuilder();
			while (!procAuthor.HasExited) {
				output.Append(procAuthor.StandardOutput.ReadToEnd());
			}
			string author = output.ToString();
			
			// fetch commit message
			Process procMessage = new Process();
			procMessage.StartInfo = new System.Diagnostics.ProcessStartInfo(svnPath + @"bin\svnlook.exe", @"log """ + args[1] + @""" -r " + args[2]);
			procMessage.StartInfo.RedirectStandardOutput = true;
			procMessage.StartInfo.UseShellExecute = false;
			procMessage.Start();
			output = new StringBuilder();
			while (!procMessage.HasExited) {
				output.Append(procMessage.StandardOutput.ReadToEnd());
			}
			string message = output.ToString();
			
			// parse out html tag characters in message
			message = Regex.Replace(message, "&", "&amp;");
			message = Regex.Replace(message, "<", "&lt;");
			message = Regex.Replace(message, ">", "&gt;");
			
			// setup request to pivotal tracker
			HttpWebRequest proxyRequest = (HttpWebRequest) HttpWebRequest.Create("http://www.pivotaltracker.com/services/v3/source_commits");
			proxyRequest.Timeout = 10000;
			proxyRequest.Method = "POST";
			proxyRequest.ContentType = "application/xml";
			proxyRequest.Headers.Add("X-TrackerToken", args[0]);

			// request body
			StreamWriter sw = new StreamWriter(proxyRequest.GetRequestStream());
			sw.Write("<source_commit><message>" + message + "</message><author>" + author + "</author><commit_id>" + args[2] + "</commit_id></source_commit>");
			sw.Close();
			
			// run the request
			HttpWebResponse proxyResponse = null;
			try {
				proxyResponse = (HttpWebResponse) proxyRequest.GetResponse();
			} catch (WebException we) {
				// status != 200, get the WebException response
				proxyResponse = (HttpWebResponse) we.Response;
				// read the response body using streamreader assuming non-binary
				StreamReader sr = new StreamReader(proxyResponse.GetResponseStream());
				string proxyRespBodyStr = sr.ReadToEnd();
				sr.Close();
				// send message to STDERR
				Console.Error.WriteLine("ERROR: " + proxyRespBodyStr);
				return 1;
			}
			
			return 0;
			
		}
		
	}
}